﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

using AwesomeEnginePC.Physics;

namespace AwesomeEnginePC.Graphics.TwoDimensional.Sprites
{
    public class BaseSprite : Base2DObject
    {
        /// <summary>
        /// The sprite image to show.
        /// </summary>
        public Texture2D SpriteTexture { get; protected set; }

        /// <summary>
        /// The SpriteEffects that are in effect on the object (if applicable).
        /// </summary>
        public virtual SpriteEffects EffectsOnSprite { get; set; }

        /// <summary>
        /// Returns the height of the sprite texture loaded. This is the height of the sprite if the ScalingY was 1.
        /// </summary>
        public virtual int RawHeight
        {
            get { return SpriteTexture.Height; }
        }

        /// <summary>
        /// Returns the width of the sprite texture loaded. This is the width of the sprite if the ScalingY was 1.
        /// </summary>
        public virtual int RawWidth
        {
            get { return SpriteTexture.Width; }
        }

        /// <summary>
        /// Gets or sets the drawn height of the sprite. This DOES take scaling into account. Setting this value only manipulates the scaling to match.
        /// </summary>
        public override int Height
        {
            get 
            {
                return (int)(SpriteTexture.Height * ScalingY);
            }
            set
            {
                ScalingY = (float)((value * 1.0) / Height);
            }
        }

        /// <summary>
        /// Gets or sets the drawn width of the sprite. This DOES take scaling into account. Setting this value only manipulates the scaling to match.
        /// </summary>
        public override int Width
        {
            get 
            {
                return (int)(SpriteTexture.Width * ScalingX);
            }
            set
            {
                ScalingX = (float)((value * 1.0) / Width);
            }
        }

        /// <summary>
        /// Gets the center point of the sprite (using raw values).
        /// </summary>
        public Vector CenterPoint
        {
            get
            {
                return new Vector(RawWidth / 2.0, RawHeight / 2.0);
            }
        }
        private Color[] colorData;
        // The color data for the images; used for per pixel collision
        public Color[] TextureData
        {
            get
            {
                return colorData;
            }
        }

        // Get the bounding of the rectangle 
        public Rectangle boundingRectangle
        {
            get
            {
                return new Rectangle((int)Position.X, (int)Position.Y,
                 Width, Height);
            }
        }

        public BaseSprite(ContentManager CM, string assetName)
            : base(CM)
        {
            SetDefaultValues();
            SetSpriteTexture(assetName);
        }

        public BaseSprite(ContentManager CM, String assetName, Vector position, Color tint)
            : base(CM)
        {
            SetSpriteTexture(assetName);
            ContentAssetName = assetName;
            Position = position;
            Tint = tint;
            Rotation = 0f;
            Origin = new Vector();
            EffectsOnSprite = SpriteEffects.None;
            LayerDepth = 0f;
            ScalingX = 1;
            ScalingY = 1;
        }

        public BaseSprite(ContentManager CM, BaseSpriteSettings settings)
            : base(CM)
        {
            SetDefaultValues();
            LoadFromSettings(settings);
        }

        protected override void SetDefaultValues()
        {
            base.SetDefaultValues();
            EffectsOnSprite = SpriteEffects.None;
        }

        public void SetSpriteTexture(string assetName)
        {
            SpriteTexture = LoadContent<Texture2D>(assetName);

            // Extract collision data
           colorData = new Color[SpriteTexture.Width * SpriteTexture.Height];
            SpriteTexture.GetData(colorData);
        }

        public void SetTexturePixels(Color[] pixels)
        {
            SpriteTexture.SetData(pixels);
        }

        public BaseSpriteSettings GetBaseSpriteSettings()
        {
            BaseSpriteSettings bss = (BaseSpriteSettings)base.GetBase2DObjectSettings();
            bss.EffectsOnSprite = this.EffectsOnSprite;
            bss.SpriteTexture = this.SpriteTexture;
            return bss;
        }

        public void LoadFromSettings(BaseSpriteSettings settings)
        {
            base.LoadFromSettings((Base2DObjectSettings)settings);

            EffectsOnSprite = settings.EffectsOnSprite;

            if (settings.SpriteTexture != null)
                SetSpriteTexture(settings.SpriteTexture.Name);
        }

        public void LoadFromSettings(Base2DObjectSettings settings, SpriteEffects effectsOnSprite, string assetName)
        {
            base.LoadFromSettings(settings);

            EffectsOnSprite = effectsOnSprite;

            if (assetName != null)
                SetSpriteTexture(assetName);
        }     

        public override void Update(GameTime gameTime)
        {
            
        }

        public override void Draw(GameTime gameTime, SpriteBatch sb)
        {
            if (Active)
            {
                sb.Draw(SpriteTexture, Position.ToVector2(), null, Tint, Rotation, Origin.ToVector2(), new Vector2(ScalingX, ScalingY), EffectsOnSprite, LayerDepth);
            }
        }

        
    }//end class
}//end namespace
